from IPython.display import Image
from IPython.core.display import HTML
sns.set_style('whitegrid', {'axes.grid' : False})
%config InlineBackend.figure_format = 'retina'
%matplotlib inline
Image(filename = "images/NILM.jpg", width=500, height=500)
Goal: Provide estimates of power demand of appliance n at time t
Image(filename = "images/smart_meter.jpg", width=400, height=400)
Tracks and records customer's home electricity use and transmits it back to electric companies
Image(filename = "images/ami.jpg", width=400, height=400, retina=True)
Existing ( As of 2015 )
Plans
Image(filename = "images/bill.jpg", width=300, height=300, retina=True)
Image(filename = "images/appliances.png", width=500, height=600, retina=True)
table = FF.create_table(example)
py.iplot(table, filename='sample_costs')
The underlying assumption in the first cost column is that the applaince is on for 5 hrs/day for a month, while being on for 24 hrs/day in the second cost column. The difference column shows the financial impact of these two cases of appliance usage. For the 5 seemingly low level appliances, a customer can expect a bill differing up to \$40/month
Image(filename = "images/process.png", width=500, height=600, retina=False)
``` | Datasets | Institution | Location | |-----------------|-----------------|--------------| | REDD (2011) | MIT | MA, USA | | BLUED (2012) | CMU | PA, USA | | Smart* (2012) | UMass | MA, USA | | Tracebase (2012)| Darmstadt | Germany | | Sample (2013) | Pecan Street | TX, USA | | HES (2013) | DECC, DEFRA | UK | | AMPds (2013) | Simon Fraser U. | BC, Canada | | iAWE (2013) | IIT Delhi | Delhi, India | | UK-DALE (2014) | Imperial College| London, UK | | DREDD (2015) | TUDelft | Netherlands | ```
Image(filename = "images/data.png", width=500, height=600, retina=False)
data.head()
print "%-25s | %-10s | %-10s | %-10s | %-10s | %-10s\n" %('Applaince', 'Min', 'Mean', 'Mode', 'Median', 'Max')
for j in data.columns:
app_data = data[j]
print "%-25s | %-10s | %-10s | %-10s | %-10s | %-10s" \
%(j, app_data.min(), round(app_data.mean(), 2), Counter(app_data).most_common(1)[0][0] ,
round(np.median(app_data.unique())), app_data.max())
fig, ax = plt.subplots(3,3, figsize=(14, 7))
bin_num = 25
color='b'
ax[0,0].hist(data.fridge, bins=bin_num, label='Fridge', color=color)
ax[0,1].hist(data.electric_heating_element, bins=bin_num, label='Elec_Heater', color=color)
ax[0,2].hist(data.cooker, bins=bin_num, label='Cooker', color=color)
ax[1,0].hist(data.sockets, bins=bin_num, label='Sockets', color=color)
ax[1,1].hist(data.toaster, bins=bin_num, label='Toaster', color=color)
ax[1,2].hist(data.laptop_computer, bins=bin_num, label='Laptop', color=color)
ax[2,0].hist(data.washing_machine, bins=bin_num, label='Washing Machine', color=color)
ax[2,1].hist(data.fan, bins=bin_num, label='Fan', color=color)
ax[2,2].hist(data.television, bins=bin_num, label='Television', color=color)
for row in range(3):
for col in range(3):
ax[row,col].set_yticklabels([])
ax[row,col].legend()
ax[0,1].set_title('Appliance Power Distributions\n', fontsize=15)
ax[1,0].set_ylabel('frequency', fontsize=14)
ax[2,1].set_xlabel('Power (Watts)', fontsize=14)
plt.show()
for appliance in model:
plt.figure(figsize=(9,3))
plt.plot(power[appliance][:86400], color='b')
plt.title("Sample %s Power" %(appliance))
plt.xlabel("index")
plt.ylabel("Power (W)");
HMM is a mixture model encoding information about the history of a time series in the value of a single multinomial variable — the hidden state — which can take on K discrete values
Image(filename = "images/fhmm.png", width=400, height=400, retina=False)
Given $\Theta${$\pi$, A, $\Phi$} & X Find optimal Z
Given $\Theta${$\pi$, A, $\Phi$} & X Find P(X|$\Theta$,X)
Given X Estimate $\Theta${$\pi$, A, $\Phi$}
Limited Horizon: $P(Z_{t}\ |\ Z_{t-1}, Z_{t-2},..., Z_{1}) = P(Z_{t}\ |\ Z_{t-1})$
Stationary Process: $P(Z_{t}\ |\ Z_{t-1}) = P(Z_{2}\ |\ Z_{1});\ t\ \in\ 2,...,T$
import plotly.plotly as py
import plotly.graph_objs as go
main = go.Scatter(x=simulation.index, y=simulation.Total, name ="Aggregate", line=dict(color='#0d2be8'), opacity=0.8)
app_1 = go.Scatter(x=simulation.index, y=simulation.Fridge, name ="Fridge", line=dict(color='#7F7F7F'), opacity=0.8)
app_2 = go.Scatter(x=simulation.index, y=simulation['Washing-Machine'], name ="Washing-Machine", line=dict(color='#46846e'), opacity=0.8)
app_3 = go.Scatter(x=simulation.index, y=simulation['E-Heater'], name="E-Heater", line=dict(color='#17BECF'), opacity=0.8)
app_4 = go.Scatter(x=simulation.index, y=simulation.Laptop, name="Laptop", line=dict(color='#2a465e'), opacity=0.8)
data = [main, app_1, app_2, app_3, app_4]
layout = dict(title = "Appliance Disaggregation")
fig = dict(data=data, layout=layout)
py.iplot(fig)
Image(filename = "images/hmms.png", width=600, height=600, retina=False)
``` | Appliance | Baseline Precision | |-----------------|---------------------| | Electric Heater | OFF: 0.72 ON: 0.28 | | Refridgerator | OFF: 0.68 ON: 0.32 | | Laptop | OFF: 0.81 ON: 0.19 | | Washing Machine | OFF: 0.99 ON: 0.01 | ```
``` | Appliance | Precision | Recall | F1-Score | |-----------------|---------------------|---------------------|---------------------| | Electric Heater | OFF: 0.89 ON: 0.82 | OFF: 0.94 ON: 0.71 | OFF: 0.91 ON: 0.76 | | Refridgerator | OFF: 0.94 ON: 0.89 | OFF: 0.95 ON: 0.88 | OFF: 0.95 ON: 0.89 | | Laptop | OFF: 0.89 ON: 0.38 | OFF: 0.76 ON: 0.61 | OFF: 0.82 ON: 0.47 | | Washing Machine | OFF: 1.00 ON: 0.14 | OFF: 0.97 ON: 0.50 | OFF: 0.98 ON: 0.22 | ```
# COMPARING TRUE VS REAL POWER DIST IN TEST SET
for appliance in model:
fig, ax = plt.subplots(1,3, figsize=(14,3), sharey=True)
ax[0].plot(power_test[appliance][:8000], color='b', label='True')
ax[0].set_title('Ground Truth Power for %s' %appliance)
ax[0].legend()
ax[1].plot(decoded_power_test[appliance][:8000], color='g', label='Predicted')
ax[1].set_title('FHMM Predicted Power for %s' %appliance)
ax[1].legend()
ax[2].plot(power_test[appliance][:8000], color='b', label='True')
ax[2].plot(decoded_power_test[appliance][:8000], color='g', label='Predicted')
ax[2].set_title('True vs. Predicted (%s)' %appliance)
ax[2].legend()
plt.ylim((np.min(power_test[appliance])-10, np.max(power_test[appliance])+10))
plt.tight_layout()
import plotly.plotly as py
import plotly.graph_objs as go
main = go.Scatter(x=simulation_test.index, y=simulation_test.Total, name="Aggregate", line=dict(color='#0d2be8'), opacity=0.8)
app_1 = go.Scatter(x=simulation_test.index, y=simulation_test.Fridge, name = "Fridge",
line = dict(color = '#7F7F7F'), opacity = 0.8)
app_2 = go.Scatter(x=simulation_test.index, y=simulation_test['Washing-Machine'], name = "Washing-Machine",
line = dict(color = '#46846e'), opacity = 0.8)
app_3 = go.Scatter(x=simulation_test.index, y=simulation_test['E-Heater'], name = "E-Heater",
line = dict(color = '#17BECF'), opacity = 0.8)
app_4 = go.Scatter(x=simulation_test.index, y=simulation_test.Laptop, name = "Laptop",
line = dict(color = '#2a465e'), opacity = 0.8)
data_test = [main, app_1, app_2, app_3, app_4]
layout = dict(title = "Predicted Disaggregation")
fig = dict(data=data_test, layout=layout)
py.iplot(fig)
``` | Appliance | RMS Baseline | RMS Model | |-----------------|-----------------|----------------| | Electric Heater | 30 W | 21 W | | Refridgerator | 44 W | 25 W | | Laptop | 11 W | 12 W | | Washing Machine | 58 W | 59 W | ```
Non-Intrusive Load Monitoring (NILM) has the potential to create additional value out of already existing metersets. The estimates at each time slice vary in terms of "closeness" for each appliance, which may suggest that the most immediate solution is to inform consumers on the usage of certain appliances. However, you lose out on reducing waste from the "unusual suspect" class of appliances.
``` |Consumer Value | Business Value | |---------------|-------------------| | Transparency | DSM | | Control | Energy Efficiency | | Save Money!!! | Dynamic Pricing | ```